use std::{borrow::Cow, net::SocketAddr};

use tweeny_rpc::macros::service;

#[service(server)]
trait CoolServ {
    async fn proc1(&self, bytes: Cow<'static, [u8]>) -> usize;
}

struct CoolServer {
    n: std::sync::atomic::AtomicU64,
}

impl CoolServ<SocketAddr> for CoolServer {
    fn proc1(
        &self,
        from: SocketAddr,
        bytes: Cow<'static, [u8]>,
    ) -> impl std::future::Future<Output = usize> + Send {
        async move {
            let n = self.n.fetch_add(bytes.len() as u64, std::sync::atomic::Ordering::Relaxed);
            n as usize  + bytes.len()
        }
    }
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    use std::{net::SocketAddr, str::FromStr, sync::Arc};
    use tweeny_rpc::server::Server;
    env_logger::init();
    let addr = SocketAddr::from_str("127.0.0.1:22331").unwrap();
    let server = Server::new_via_tcp(
        Arc::new(CoolServRpcServ(CoolServer {
            n: std::sync::atomic::AtomicU64::new(0),
        })),
        addr,
    )
    .await?;
    println!("{:?}", tokio::spawn(server.serve()).await);
    Ok(())
}
